<a href="^Code::c:s0p0">Fig. 10.1</a> Demonstrating polymorphism with the <b>Employee</b> class hierarchy.<br>
<a href="^Code::c:s0p1">Fig. 10.2</a> Definition of abstract base class <b>Shape</b>.<br>
<a href="^Illustration::c:s0p1">Fig. 10.3</a> Flow of control of a virtual function call.<br>
<br>
</page>
<page>
<font size=18><a href="~audio/Ch10/10fig003.au"><img src="bckgrnds/icons/audio.gif" align=sidebar></a>Figure 10.3 - Flow of control of a <b>virtual</b> function call. (Part 1 of 3)</font><br>
<img src="graphics/ch10/fig1003a.gif" ><br>
</page>
<page>
<font size=18>Figure 10.3 - Flow of control of a <b>virtual</b> function call. (Part 2 of 3) </font><br>
<img src="graphics/ch10/fig1003b.gif" ><br>
</page>
<page>
<font size=18>Figure 10.3 - Flow of control of a <b>virtual</b> function call. (Part 3 of 3) </font><br>
a) Using inheritance and polymorphism helps eliminate ________ logic.<br>
b) A pure <b>virtual</b> function is specified by placing ________ at the end of its
prototype in the class definition.<br>
c) If a class contains one or more pure <b>virtual</b> functions, it is an ________.<br>
d) A function call resolved at compile time is referred to as ________
binding.<br>
e) A function call resolved at run time is referred to as ________ binding.<br>
<foreign name="answers" url="^Answers::c:s0p0">
<br>
<br>
</page>
<page pagename="Exercise 10.2">
<b>Exercise 10.2</b><br>
What are <b>virtual</b> functions? Describe a circumstance in which <b>virtual</b> functions
would be appropriate. <br>
<br>
<br>
</page>
<page pagename="Exercise 10.3">
<b>Exercise 10.3</b><br>
Given that constructors cannot be <b>virtual</b>, describe a scheme for how you might
achieve a similar effect.<br>
<br>
<br>
</page>
<page pagename="Exercise 10.4">
<b>Exercise 10.4</b><br>
How is it that polymorphism enables you to program "in the general" rather than
"in the specific." Discuss the key advantages of programming "in the general."<br>
<br>
<br>
</page>
<page pagename="Exercise 10.5">
<b>Exercise 10.5</b><br>
Discuss the problems of programming with <b>switch</b> logic. Explain why
polymorphism is an effective alternative to using <b>switch</b> logic.<br>
<br>
<br>
</page>
<page pagename="Exercise 10.6">
<b>Exercise 10.6</b><br>
Distinguish between static binding and dynamic binding. Explain the use of
<b>virtual</b> functions and the <i>vtable</i> in dynamic binding.<br>
<foreign name="answers" url="^Answers::c:s0p1">
<br>
</page>
<page pagename="Exercise 10.7">
<b>Exercise 10.7</b><br>
Distinguish between inheriting interface and inheriting implementation. How do
inheritance hierarchies designed for inheriting interface differ from those
designed for inheriting implementation?<br>
<foreign name="answers" url="^Answers::c:s0p3">
<br>
</page>
<page pagename="Exercise 10.8">
<b>Exercise 10.8</b><br>
Distinguish between <b>virtual</b> functions and pure <b>virtual</b> functions.<br>
<br>
</page>
<page pagename="Exercise 10.9">
<b>Exercise 10.9</b><br>
(True/False) All <b>virtual</b> functions in an abstract base class must be declared as
pure <b>virtual</b> functions.<br>
<br>
<br>
</page>
<page pagename="Exercise 10.10">
<b>Exercise 10.10</b><br>
Suggest one or more levels of abstract base classes for the <b>Shape</b> hierarchy
discussed in this chapter (the first level is <b>Shape</b> and the second level consists of
the classes <b>TwoDimensionalShape</b> and <b>ThreeDimensionalShape</b>).<br>
<br>
<br>
</page>
<page pagename="Exercise 10.11">
<b>Exercise 10.11</b><br>
How does polymorphism promote extensibility?<br>
<br>
<br>
</page>
<page pagename="Exercise 10.12">
<b>Exercise 10.12</b><br>
You have been asked to develop a flight simulator that will have elaborate
graphical outputs. Explain why polymorphic programming would be especially
effective for a problem of this nature.<br>
<br>
<br>
</page>
<page pagename="Exercise 10.13">
<b>Exercise 10.13</b><br>
Develop a basic graphics package. Use the <b>Shape</b> class inheritance hierarchy
from Chapter 9. Limit yourself to two-dimensional shapes such as squares,
rectangles, triangles and circles. Interact with the user. Let the user specify the
position, size, shape and fill characters to be used in drawing each shape. The
user can specify many items of the same shape. As you create each shape, place
a <b>Shape *</b> pointer to each new <b>Shape</b> object into an array. Each class has its own
draw member function. Write a polymorphic screen manager that walks
through the array (preferably using an iterator) sending <b>draw</b> messages to each
object in the array to form a screen image. Redraw the screen image each time
the user specifies an additional shape.<br>
<br>
</page>
<page pagename="Exercise 10.14">
<b>Exercise 10.14</b><br>
Modify the payroll system of <a href="^Code::c:s0p0"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.1</a> to add private data members <b>birthDate</b>
(a <b>Date</b> object) and <b>departmentCode</b> (an <b>int</b>) to class <b>Employee</b>. Assume this
payroll is processed once per month. Then, as your program calculates the
payroll for each <b>Employee</b> (polymorphically), add a $100.00 bonus to the
person's payroll amount if this is the month in which the <b>Employee</b>'s birthday
occurs.<br>
<foreign name="answers" url="^Answers::c:s0p5">
</page>
<page pagename="Exercise 10.15">
<b>Exercise 10.15</b><br>
In Exercise 9.14, you developed a <b>Shape</b> class hierarchy and defined the classes
in the hierarchy. Modify the hierarchy so that class <b>Shape</b> is an abstract base
class containing the interface to the hierarchy. Derive <b>TwoDimensionalShape</b>
and <b>ThreeDimensionalShape</b> from class <b>Shape</b>--these classes should also be
abstract. Use a <b>virtual print</b> function to output the type and dimensions of each
class. Also include <b>virtual area</b> and <b>volume</b> functions so these calculations can
be performed for objects of each concrete class in the hierarchy. Write a driver
program that tests the <b>Shape</b> class hierarchy.<br>
With <i>virtual functions</i> and <i>polymorphism</i>, it is possible
to design and implement systems that are more easily
<i>extensible</i>. Programs can be written to generically
process--as base-class objects--objects of all existing
classes in a hierarchy. Classes that do not exist during
program development can be added with little or no
modifications to the generic part of the program--as
long as those classes are part of the hierarchy that is
being processed generically. The only parts of a
program that will need modification are those parts that <br>
</page>
<page>
require direct knowledge of the particular class that is
added to the hierarchy.<br>
</page>
</section>
<section type=Body name=Default title="10.2 Type Fields and switch Statements">
<page>
<font size=18 bold>10.2 Type Fields and <tt>switch</tt> Statements</font><hr>
One means of dealing with objects of different types is
to use a <b>switch</b> statement to take an appropriate action
on each object based on that object's type. For example,
in a hierarchy of shapes in which each shape specifies
its type as a data member, a <b>switch</b> structure could
determine which <b>print</b> function to call based on the
type of the particular object. <br>
<spacer width=16 height=1>There are many problems with using <b>switch</b> logic. The
programmer might forget to make such a type test when
one is warranted. The programmer may forget to test all
possible cases in a <b>switch</b>. If a <b>switch</b>-based system is <br>
</page>
<page>
modified by adding new types, the programmer might
forget to insert the new cases in all existing <b>switch</b>
statements. Every addition or deletion of a class to
handle new types demands that every <b>switch</b> statement
in the system be modified; tracking these down can be
time consuming and error-prone. <br>
<spacer width=16 height=1><a href="^Engineer::c:s0p0"><img src="bckgrnds/icons/seo_ico.gif" align=sidebar></a>As we will see, <b>virtual</b> functions and polymorphic
programming can eliminate the need for <b>switch</b> logic.
The programmer can use the <b>virtual</b> function
mechanism to perform the equivalent logic
automatically, thus avoiding the kinds of errors
typically associated with <b>switch</b> logic.<br>
Suppose a set of shape classes such as <b>Circle</b>, <b>Triangle</b>,
<b>Rectangle</b>, <b>Square</b>, etc. are all derived from base class
<b>Shape</b>. In object-oriented programming, each of these
classes might be endowed with the ability to draw itself.
Although each class has its own <b>draw</b> function, the
<b>draw</b> function for each shape is quite different. When
drawing a shape, whatever that shape may be, it would
be nice to be able to treat all these shapes generically as
objects of the base class <b>Shape</b>. Then to draw any
shape, we could simply call function <b>draw</b> of base class
<b>Shape</b> and let the program determine <i>dynamically</i> (i.e., <br>
</page>
<page>
at execution time) which derived class <b>draw</b> function to
use. <br>
<spacer width=16 height=1><a href="^Engineer::c:s0p2"><img src="bckgrnds/icons/seo_ico.gif" align=sidebar></a>To enable this kind of behavior, we declare draw in the
base class as a <b><i>virtual function</i></b> and we <i>override</i> <b>draw</b> in
each of the derived classes to draw the appropriate
shape. <a href="^Practice::c:s0p0"><img src="bckgrnds/icons/gpp_ico.gif" align=sidebar></a>A virtual function is declared by preceding the
function's prototype with the keyword <b>virtual</b> in the
base class. For example, <br>
<font size=2><br></font><font size=11><pre>
virtual void draw() const;<p>
</pre></font>
may appear in base-class <b>Shape</b>. The preceding
prototype declares that function <b>draw</b> is a constant
function that takes no arguments, returns nothing and is
a <b>virtual</b> <b><a href="^Engineer::c:s0p3"><img src="bckgrnds/icons/seo_ico.gif" align=sidebar></a></b>function. <br>
</page>
<page>
If function <b>draw</b> in the base class has been declared
<b>virtual</b>, and if we then use a base-class pointer or
reference to point to the derived-class object and invoke
the <b>draw</b> function using this pointer (e.g., <b>shapePtr-
>draw()</b>) or reference, the program will choose the
correct derived class's <b>draw</b> function dynamically (i.e.,
at execution time). Such <i>dynamic binding</i> will be
illustrated in the case studies in<a href="#s6p0"> Sections 10.6</a> and<a href="#s9p0"> 10.9</a>.<br>
<spacer width=16 height=1>When a <b>virtual</b> function is called by referencing a
specific object by name and using the dot member
selection operator (e.g., <b>squareObject.draw()</b>), the
reference is resolved at compile time (this is called
<i>static binding</i>) and the <b>virtual</b> function that is called is <br>
</page>
<page>
the one defined for (or inherited by) the class of that
Dynamic binding is the process by which a function call through a base class pointer is resolved at runtime to determine which derived class virtual function to invoke. <br>
<component type="checkbox" width=20 height=18 label="" name="" feedback="False. Static binding occurs at compile-time if a specific object invokes the virtual function.">
Dynamic binding is always used for virtual functions. <br>
<component type=button name=b label="Check Your Answer" width=125 height=24>
</page>
</section>
<section type=Body name=Default title="10.4 Abstract Base Classes and Concrete Classes">
<page>
<font size=18 bold>10.4 Abstract Base Classes and Concrete
Classes</font><hr>
When we think of a class as a type, we assume that
objects of that type will be instantiated. However, there
are cases in which it is useful to define classes for
which the programmer never intends to instantiate any
objects. Such classes are called <i>abstract classes</i>.
Because these are used as base classes in inheritance
situations, we normally will refer to them as <i>abstract
base classes</i>. No objects of an abstract base class can be
instantiated.<br>
</page>
<page>
The sole purpose of an abstract class is to provide an
appropriate base class from which classes may inherit
interface and/or implementation. Classes from which
objects can be instantiated are called <i>concrete classes</i>.<br>
<spacer width=16 height=1>We could have an abstract base class
<b>TwoDimensionalShape</b> and derive concrete classes
such as <b>Square</b>, <b>Circle</b>, <b>Triangle</b>, etc. We could also
have an abstract base class <b>ThreeDimensionalShape</b>
and derive concrete classes such as <b>Cube</b>, <b>Sphere</b>,
<b>Cylinder</b>, etc. <a href="^Errors::c:s0p0"><img src="bckgrnds/icons/cpe_ico.gif" align=sidebar></a>Abstract base classes are too generic to
define real objects; we need to be more specific before
we can think of instantiating objects. That is what <br>
</page>
<page>
concrete classes do; they provide the specifics that
make it reasonable to instantiate objects.<br>
<spacer width=16 height=1><a href="^Engineer::c:s0p4"><img src="bckgrnds/icons/seo_ico.gif" align=sidebar></a>A class is made abstract by declaring one or more of its
<tt><b>virtual</b></tt> functions to be "pure." A <i>pure</i> <b><i>virtual</i></b>
<i>function</i> is one with an <i>initializer of <tt><b>=</b></tt> <tt><b>0</b></tt></i> in its
declaration as in<br>
<font size=2><br></font><font size=11><pre>
virtual float earnings() const = 0; // pure virtual <p>
</pre></font>
A hierarchy does not need to contain any abstract
classes, but as we will see, many good object-oriented
systems have class hierarchies headed by an abstract
base class. In some cases, abstract classes constitute the
top few levels of the hierarchy. A good example of this <br>
</page>
<page>
is a shape hierarchy. The hierarchy could be headed by
abstract base class <b>Shape</b>. On the next level down, we
can have two more abstract base classes, namely
<b>TwoDimensionalShape</b> and
<b>ThreeDimensionalShape</b>. The next level down would
start defining concrete classes for two-dimensional
shapes such as circles and squares, and concrete classes
for three-dimensional shapes such as spheres and cubes.<br>
Abstract base classes can be used for inheritance. <br>
<component type="checkbox" width=20 height=18 label="" name="" feedback="False. Concrete classes are classes from which objects can be instantiated (i.e., non-abstract classes).">
Concrete classes are classes that cannot be used as base classes. <br>
Through the use of virtual functions and polymorphism, one member function call can cause different actions to occur depending on the type of the object receiving the call. <br>
<component type="checkbox" width=20 height=18 label="" name="" feedback=" False. Polymorphism is referred to as "programming in the general."">
Polymorphism can be thought of as "programming in the specific." <br>
<component type=button name=b label="Check Your Answer" width=125 height=24>
</page>
</section>
<section type=Body name=Default title="10.6 Case Study: A Payroll System Using Polymorphism">
<page>
<font size=18 bold>10.6 Case Study: A Payroll System Using
Polymorphism</font><hr>
Let us use <b>virtual</b> functions and polymorphism to
perform payroll calculations based on the type of an
employee (<a href="^Code::c:s0p0"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.1</a>). We use a base class <b>Employee</b>.
The derived classes of <b>Employee</b> are <b>Boss</b> who gets
paid a fixed weekly salary regardless of the number of
hours worked, <b>CommissionWorker</b> who gets a flat
base salary plus a percentage of sales, <b>PieceWorker</b>
who gets paid by the number of items produced, and
<b>HourlyWorker</b> who gets paid by the hour and receives
overtime pay. <br>
</page>
<page>
An <b>earnings</b> function call certainly applies generically
to all employees. But the way each person's earnings
are calculated depends on the class of the employee,
and these classes are all derived from the base class
<b>Employee</b>. So <b>earnings</b> is declared pure <b>virtual</b> in base
class <b>Employee</b> and appropriate implementations of
<b>earnings</b> are provided for each of the derived classes.
Then, to calculate any employee's earnings, the
program simply uses a base-class pointer (or reference)
to that employee's object and invokes the <b>earnings</b>
function. In a real payroll system, the various employee
objects might be pointed to by individual elements in an
array (or list) of pointers of type <b>Employee *</b>. The <br>
</page>
<page>
program would simply walk through the array one
element at a time using the <b>Employee *</b> pointers to
invoke the <b>earnings</b> function of each object.<br>
<spacer width=16 height=1>Let us consider the <b>Employee</b> class (<a href="^Code::c:s0p0"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.1</a>, parts 1
and 2). The <b>public</b> member functions include a
constructor that takes the first name and last name as
arguments; a destructor that reclaims dynamically
allocated memory; a <i>get</i> function that returns the first
name; a <i>get</i> function that returns the last name; a pure
<b>virtual</b> function <b>earnings</b>; and a <b>virtual</b> function <b>print</b>.
Why is <b>earnings</b> pure <b>virtual</b>? The answer is that it
does not make sense to provide an implementation of
this function in the <b>Employee</b> class. We cannot <br>
</page>
<page>
calculate the earnings for a generic employee--we must
first know what kind of employee it is. By making this
function pure <b>virtual</b> we are indicating that we will
provide an implementation of this function in each
derived class, but not in the base class itself. The
programmer never intends to call this pure <b>virtual</b>
function in the abstract base class <b>Employee</b>; all
derived classes will override <b>earnings</b> with appropriate
implementations for those classes.<br>
<spacer width=16 height=1>Class <b>Boss</b> (<a href="^Code::c:s0p0"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.1</a>, parts 3 and 4) is derived from
<b>Employee</b> with <b>public</b> inheritance. The <b>public</b> member
functions include a constructor that takes a first name, a
last name and a weekly salary as arguments, and passes <br>
</page>
<page>
the first name and last name to the <b>Employee</b>
constructor to initialize the <b>firstName</b> and <b>lastName</b>
members of the base-class part of the derived-class
object; a <i>set</i> function to assign a new value to <b>private</b>
data member <b>weeklySalary</b>; a virtual <b>earnings</b>
function defining how to calculate a <b>Boss</b>'s earnings;
and a <b>virtual print</b> function that outputs the type of the
employee then calls <b>Employee::print()</b> to output the
employee's name.<br>
<spacer width=16 height=1>Class <b>CommissionWorker</b> (<a href="^Code::c:s0p0"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.1</a>, parts 5 and 6) is
derived from <b>Employee</b> with <b>public</b> inheritance. The
<b>public</b> member functions include a constructor that
takes a first name, a last name, a salary, a commission <br>
</page>
<page>
and a quantity of items sold as arguments, and passes
the first name and last name to the <b>Employee</b>
constructor; <i>set</i> functions to assign new values to
<b>private</b> data members <b>salary</b>, <b>commission</b> and
<b>quantity</b>; a <b>virtual earnings</b> function defining how to
calculate a <b>CommissionWorker</b>'s earnings; and a
<b>virtual print</b> function that outputs the type of the
employee then calls <b>Employee::print(<tt>)</tt></b> to output the
employee's name.<br>
<spacer width=16 height=1>Class <b>PieceWorker</b> (<a href="^Code::c:s0p0"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.1</a>, parts 7, 8 and 9) is
derived from <b>Employee</b> with <b>public</b> inheritance. The
<b>public</b> member functions include a constructor that
takes a first name, a last name, a wage per piece and a <br>
</page>
<page>
quantity of items produced as arguments, and passes the
first name and last name to the <b>Employee</b> constructor;
set functions to assign new values to private data
members <b>wagePerPiece</b> and <b>quantity</b>; a <b>virtual
earnings</b> function defining how to calculate a
<b>PieceWorker</b>'s earnings; and a <b>virtual print</b> function
that outputs the type of the employee then calls
<b>Employee::print()</b> to output the employee's name.<br>
<spacer width=16 height=1>Class <b>HourlyWorker</b> (<a href="^Code::c:s0p0"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.1</a>, parts 10 and 11) is
derived from <b>Employee</b> with <b>public</b> inheritance. The
<b>public</b> member functions include a constructor that
takes a first name, a last name, a wage and the number
of hours worked as arguments and passes the first name <br>
</page>
<page>
and last name to the <b>Employee</b> constructor to initialize
the <b>firstName</b> and <b>lastName</b> members of the base-class
part of the derived-class object; <i>set</i> functions to assign
new values to <b>private</b> data members <b>wage</b> and <b>hours</b>; a
<b>virtual earnings</b> function defining how to calculate an
<b>HourlyWorker</b>'s earnings; and a <b>virtual print</b>
function that outputs the type of the employee then calls
<b>Employee::print()</b> to output the employee's name.<br>
<spacer width=16 height=1>The driver program and program outputs are shown in
<a href="^Code::c:s0p0"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.1</a>, parts 12 and 13. Each of the four code
segments in <b>main</b> is similar, so we discuss only the first
segment, which deals with a <b>Boss</b> object. <br>
<spacer width=16 height=1>Line 302<br>
</page>
<page>
<font size=2><br></font><font size=11><pre>
Boss b( "John", "Smith", 800.00 );<p>
</pre></font>
instantiates derived-class object b of class <b>Boss</b> and
provides the constructor arguments including the first
name, the last name and the fixed weekly salary.<br>
<spacer width=16 height=1>Line 303<br>
<font size=2><br></font><font size=11><pre>
b.print(); // static binding<p>
</pre></font>
explicitly invokes the <b>Boss</b> version of member function
<b>print</b> by using the dot member selection operator off
the specific <b>Boss</b> object <b>b</b>. This is an example of static
binding because the type of the object for which the
function is being called is known at compile time. This
call is included for comparison purposes to illustrate <br>
</page>
<page>
that the correct <b>print</b> function is invoked using dynamic
binding.<br>
<spacer width=16 height=1>Line 304<br>
<font size=2><br></font><font size=11><pre>
cout << " earned $" << b.earnings();<p>
// static binding<p>
</pre></font>
explicitly invokes the <b>Boss</b> version of member function
<b>earnings</b> by using the dot member selection operator
off the specific <b>Boss</b> object <b>b</b>. This is also an example
of static binding. This call is also included for
comparison purposes, this time to illustrate that the
correct <b>earnings</b> function is invoked using dynamic
binding.<br>
</page>
<page>
Line 305<br>
<font size=2><br></font><font size=11><pre>
virtualViaPointer( &b ); <p>
// uses dynamic binding<p>
</pre></font>
invokes function <b>virtualViaPointer</b> (line 331) with the
address of derived class object <b>b</b>. The function receives
this address in its parameter <b>baseClassPtr</b> which is
declared as a <b>const Employee *</b>. This is precisely how
to effect polymorphic behavior.<br>
<spacer width=16 height=1>Line 333<br>
<font size=2><br></font><font size=11><pre>
baseClassPtr->print();<p>
</pre></font>
invokes member function <b>print</b> of the object pointed to
by <b>baseClassPtr</b>. Because <b>print</b> is declared <b>virtual</b> in
the base class, the system invokes the derived class <br>
</page>
<page>
object's <b>print</b> function--precisely what is called
polymorphic behavior. This function call is an example
of dynamic binding--the <b>virtual</b> function is invoked
through a base-class pointer, so the decision as to what
function to invoke is deferred until execution time.<br>
hierarchy. If an object is destroyed explicitly by
applying the <b>delete</b> operator to a base-class pointer to
the object, the base-class destructor function is called
on the object. This occurs regardless of the type of the
object to which the base-class pointer is pointing and
regardless of the fact that each class's destructor has a
different name. <br>
<spacer width=16 height=1><a href="^Errors::c:s0p1"><img src="bckgrnds/icons/cpe_ico.gif" align=sidebar></a>There is a simple solution to this problem--declare a
<b>virtual</b> base-class destructor. This automatically makes <br>
</page>
<page>
all derived-class destructors <b>virtual</b> even though they
do not have the same name as the base-class destructor.
Now, if an object in the hierarchy is destroyed explicitly
by applying the <b>delete</b> operator to a base-class pointer
to a derived-class object, the destructor for the
appropriate class is called. <a href="^Practice::c:s0p2"><img src="bckgrnds/icons/gpp_ico.gif" align=sidebar></a>Remember, when a derived-
class object is destroyed, the base-class part of the
derived-class object is also destroyed--the base-class
destructor automatically executes after the derived-
Declaring a base class destructor virtual results in all derived class destructors being implicitly virtual. <br>
<component type=button name=b label="Check Your Answer" width=125 height=24>
</page>
</section>
<section type=Body name=Default title="10.9 Case Study: Inheriting Interface and Implementation">
<page>
<font size=18 bold>10.9 Case Study: Inheriting Interface and
Implementation</font><hr>
Our next example (<a href="^Code::c:s0p1"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.2</a>) re-examines the <b>Point</b>,
<b>Circle</b>, <b>Cylinder</b> hierarchy from the previous chapter
except that we now head the hierarchy with abstract
base class <b>Shape</b>. <b>Shape</b> has two pure <b>virtual</b>
functions--<b>printShapeName</b> and <b>print</b>--so <b>Shape</b> is
an abstract base class. <b>Shape</b> contains two other <b>virtual</b>
functions, <b>area</b> and <b>volume</b>, each of which has a default
implementation that returns a value of zero. <b>Point</b>
inherits these implementations from <b>Shape</b>. This makes
sense because both the area and volume of a point are <br>
</page>
<page>
zero. <b>Circle</b> inherits the <b>volume</b> function from <b>Point</b>,
but <b>Circle</b> provides its own implementation for the
<b>area</b> function. <b>Cylinder</b> provides its own
implementations for both the <b>area</b> function and the
<b>volume</b> function.<br>
<spacer width=16 height=1>Note that although <b>Shape</b> is an abstract base class, it
still contains implementations of certain member
functions, and these implementations are inheritable.
The <b>Shape</b> class provides an inheritable interface in the
form of four <b>virtual</b> functions that all members of the
hierarchy will contain. The <b>Shape</b> class also provides
some implementations that derived classes in the first
few levels of the <a href="^Engineer::c:s0p12"><img src="bckgrnds/icons/seo_ico.gif" align=sidebar></a>hierarchy will use.<br>
</page>
<page>
Base class <b>Shape</b> (<a href="^Code::c:s0p1"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.2</a>, part 1) consists of four
<b>public virtual</b> functions and does not contain any data.
Functions <b>printShapeName</b> and <b>print</b> are pure <b>virtual</b>,
so they are overridden in each of the derived classes.
Functions <b>area</b> and <b>volume</b> are defined to return <b>0.0</b>.
These functions are overridden in derived classes when
it is appropriate for those classes to have a different
<b>area</b> calculation and/or a different <b>volume</b> calculation.
Note that <b>Shape</b> is an abstract class and it contains
some "impure" <b>virtual</b> functions (<b>area</b> and <b>volume</b>).
Abstract classes can also include non-<b>virtual</b> functions
and data which will be inherited by derived classes.<br>
</page>
<page>
Class <b>Point</b> (<a href="^Code::c:s0p1"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.2</a>, parts 2 and 3) is derived from
<b>Shape</b> with <b>public</b> inheritance. A <b>Point</b> has an area of
<b>0.0</b> and a volume of <b>0.0</b>, so the base-class member
functions <b>area</b> and <b>volume</b> are not overridden here--
they are simply inherited as defined in <b>Shape</b>.
Functions <b>printShapeName</b> and <b>print</b> are
implementations of <b>virtual</b> functions that were defined
as pure <b>virtual</b> in the base class--if we did not override
these functions in class <b>Point</b>, then <b>Point</b> would also be
an abstract class and we would not be able to instantiate
<b>Point</b> objects. Other member functions include a <i>set</i>
function to assign new <b>x</b> and <b>y</b> coordinates to a <b>Point</b> <br>
</page>
<page>
and <i>get</i> functions to return the <b>x</b> and <b>y</b> coordinates of a
<b>Point</b>. <br>
<spacer width=16 height=1>Class <b>Circle</b> (<a href="^Code::c:s0p1"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.2</a>, parts 4 and 5) is derived from
<b>Point</b> with <b>public</b> inheritance. A <b>Circle</b> has a volume
of <b>0.0</b>, so base-class member function <b>volume</b> is not
overridden here--it is inherited from <b>Point</b> which
previously inherited <b>volume</b> from <b>Shape</b>. A <b>Circle</b> has
non-zero area, so the <b>area</b> function is overridden in this
class. Functions <b>printShapeName</b> and <b>print</b> are
implementations of <b>virtual</b> functions that were defined
as pure <b>virtual</b> in the <b>Shape</b> class. If these functions are
not overridden here, the <b>Point</b> versions of these
functions would be inherited. Other member functions <br>
</page>
<page>
include a <i>set</i> function to assign a new <b>radius</b> to a <b>Circle</b>
and a <i>get</i> function to return the <b>radius</b> of a <b>Circle</b>. <br>
<spacer width=16 height=1>Class <b>Cylinder</b> (<a href="^Code::c:s0p1"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.2</a>, parts 6 and 7) is derived
from <b>Circle</b> with <b>public</b> inheritance. A <b>Cylinder</b> has
area and volume different from those of <b>Circle</b>, so the
<b>area</b> and <b>volume</b> functions are both overridden in this
class. Functions <b>printShapeName</b> and <b>print</b> are
implementations of <b>virtual</b> functions that were defined
as pure <b>virtual</b> in the <b>Shape</b> class. If these functions are
not overridden here, the <b>Circle</b> versions of these
functions would be inherited. Other member functions
include <i>set</i> and <i>get</i> functions to assign a new <b>height</b> and
return the <b>height</b> of a <b>Cylinder</b>, respectively.<br>
</page>
<page>
The driver program (<a href="^Code::c:s0p1"><img src="bckgrnds/icons/code_ico.gif" align=sidebar>Fig. 10.2</a>, parts 8, 9 and 10) begins
by instantiating <b>Point</b> object <b>point</b>, <b>Circle</b> object <b>circle</b>
and <b>Cylinder</b> object <b>cylinder</b>. Functions
<b>printShapeName</b> and <b>print</b> are invoked for each
object to print the name of the object and to illustrate
that the objects are initialized correctly. Each call to
<b>printShapeName</b> and <b>print</b> in lines 164 through 173
uses static binding--at compile time the compiler
knows the type of each object for which
<b>printShapeName</b> and <b>print</b> are called. <br>
<spacer width=16 height=1>Next, array <b>arrayOfShapes</b>, each element of which is
of type <b>Shape *</b>, is declared. This array of base-class
pointers is used to point to each of the derived-class <br>
</page>
<page>
objects. The address of object <b>point</b> is assigned to
<b>arrayOfShapes[ 0 ]</b> (line 179), the address of object
<b>circle</b> is assigned to <b>arrayOfShapes[ 1 ]</b> (line 182) and
the address of object <b>cylinder</b> is assigned to
<b>arrayOfShapes[ 2 ]</b> (line 185). <br>
<spacer width=16 height=1>Next, a <b>for</b> structure (line 193) walks through the array
<b>arrayOfShapes</b> and invokes function
<b>virtualViaPointer</b> (line 194)<br>
<font size=2><br></font><font size=11><pre>
virtualViaPointer( arrayOfShapes[ i ] );<p>
</pre></font>
for each element of the array. Function
<b>virtualViaPointer</b> receives in parameter <b>baseClassPtr</b>
(of type <b>const Shape *</b>) the address stored in an
element of <b>arrayOfShapes</b>. Each time <br>
</page>
<page>
<b>virtualViaPointer</b> executes, the following four <b>virtual</b>
function calls are made <br>
<font size=2><br></font><font size=11><pre>
baseClassPtr->printShapeName()<p>
baseClassPtr->print()<p>
baseClassPtr->area()<p>
baseClassPtr->volume()<p>
</pre></font>
Each of these calls invokes a <b>virtual</b> function on the
object to which <b>baseClassPtr</b> points at execution
time--an object whose type cannot be determined here
at compile time. The output illustrates that the
appropriate functions for each class are invoked. First,
the string "<b>Point: </b>" and the coordinates of the object
<b>point</b> are output; the area and volume are both <b>0.00</b>. <br>
</page>
<page>
Next, the string "<b>Circle: </b>", the coordinates of the
center of object <b>circle</b> and the radius of object <b>circle</b> are
output; the area of <b>circle</b> is calculated and the volume is
returned as <b>0.00</b>. Finally, the string "<b>Cylinder: </b>", the
coordinates of the center of the base of object <b>cylinder</b>,
the radius of object <b>cylinder</b> and the height of object
<b>cylinder</b> are output; the area of <b>cylinder</b> is calculated
and the volume of <b>cylinder</b> is calculated. All the
<b>virtual</b> function calls to <b>printShapeName</b>, <b>print</b>, <b>area</b>
and <b>volume</b> are resolved at run-time with dynamic
binding.<br>
</page>
<page>
Finally, a <b>for</b> structure (line 202) walks through
<b>arrayOfShapes</b> and invokes function
<b>virtualViaReference</b> (line 203)<br>
<font size=2><br></font><font size=11><pre>
virtualViaReference( *arrayOfShapes[ j ] );<p>
</pre></font>
for each element of the array. Function
<b>virtualViaReference</b> receives in its parameter
<b>baseClassRef</b> (of type <b>const Shape &</b>), a reference
formed by dereferencing the address stored in an
element of the array. During each call to
<b>virtualViaReference</b>, the following <b>virtual</b> function
calls are made <br>
<font size=2><br></font><font size=11><pre>
baseClassRef.printShapeName()<p>
baseClassRef.print()<p><p>
</pre></font>
</page>
<page>
<font size=2><br></font><font size=11><pre>
baseClassRef.area()<p>
baseClassRef.volume()<p>
</pre></font>
Each of the preceding calls invokes these functions on
the object to which <b>baseClassRef</b> refers. The output
produced using base-class references is identical to the
output produced using base-class pointers.<br>
</page>
</section>
<section type=Body name=Default title="10.10 Polymorphism, virtual Functions and Dynamic Binding "Under the Hood"">
<page>
<font size=18 bold>10.10 Polymorphism, <tt>virtual</tt> Functions and
Dynamic Binding "Under the Hood"</font><hr>
C++ makes polymorphism easy to program. It is
certainly possible to program for polymorphism in non-
object-oriented languages such as C, but doing so
requires complex and potentially dangerous pointer
manipulations. In this section we discuss how C++
implements polymorphism, <b>virtual</b> functions and
dynamic binding internally. This will give you a solid
understanding of how these capabilities really work.
More importantly, it will help you appreciate the
overhead of polymorphism--in additional memory <br>
</page>
<page>
consumption and processor time. This will help you
determine when to use polymorphism and when to
avoid it. As you will see in Chapter 20, "Standard
Template Library (STL)," the STL components were
implemented without polymorphism and <b>virtual</b>
functions--this was done to avoid execution-time
overhead and achieve optimal performance to meet the
unique requirements of the STL.<br>
<spacer width=16 height=1>First, we will explain the data structures the C++
compiler builds at compile time to support
polymorphism at execution time. Then, we will show
how an executing program uses these data structures to <br>
</page>
<page>
execute <b>virtual</b> functions and achieve the dynamic
binding associated with polymorphism.<br>
<spacer width=16 height=1>When C++ compiles a class that has one or more
<b>virtual</b> functions, it builds a <b><i>virtual function table
(vtable)</i></b> for that class. The <i>vtable</i> is used by the
executing program to select the proper function
implementations each time a <b>virtual</b> function of that
class is to be executed. <a href="^Illustration::c:s0p1"><img src="bckgrnds/icons/ill_ico.gif" align=sidebar>Figure 10.3</a> illustrates the
<b>virtual</b> function tables for classes <b>Shape</b>, <b>Point</b>, <b>Circle</b>
and <b>Cylinder</b>.<br>
<spacer width=16 height=1>In the <i>vtable</i> for class <b>Shape</b>, the first function pointer
points to the implementation of the <b>area</b> function for
that class, namely a function that returns an area of <b>0.0</b>. <br>
</page>
<page>
The second function pointer points to the <b>volume</b>
function which also returns <b>0.0</b>. The <b>printShapeName</b>
and <b>print</b> functions are each pure <b>virtual</b>--they lack
implementations so their function pointers are each set
to <b>0</b>. Any class that has one or more <b>0</b> pointers in its
<i>vtable</i> is an abstract class. Classes without any <b>0</b> <i>vtable</i>
pointers (as <b>Point</b>, <b>Circle</b> and <b>Cylinder</b>) are concrete
classes.<br>
<spacer width=16 height=1>Class <b>Point</b> inherits the <b>area</b> and <b>volume</b> functions of
class <b>Shape</b>, so the compiler simply sets these two
pointers in the <i>vtable</i> for class <b>Point</b> to be copies of the
<b>area</b> and <b>volume</b> pointers in class <b>Shape</b>. Class <b>Point</b>
overrides function <b>printShapeName</b> to print <tt><b>"Point: "</b></tt> <br>
</page>
<page>
so the function pointer points to the <b>printShapeName</b>
function of class <b>Point</b>. <b>Point</b> also overrides <b>print</b> so
the corresponding function pointer points to the <b>Point</b>
class function that prints <b>[ x, y ]</b>.<br>
<spacer width=16 height=1>The <b>Circle area</b> function pointer in the <i>vtable</i> for class
<b>Circle</b> points to the <b>Circle area</b> function that returns
p<b>r2</b>. The <b>volume</b> function pointer is simply copied
from the <b>Point</b> class--that pointer was previously
copied into <b>Point</b> from <b>Shape</b>. The <b>printShapeName</b>
function pointer points to the <b>Circle</b> version of the
function which prints <tt><b>"Circle: "</b></tt>. The <b>print</b> function
pointer points to <b>Circle</b>'s <b>print</b> function that prints <b>[ x,
y ] r</b>. <br>
</page>
<page>
The <b>Cylinder</b> <b>area</b> function pointer in the <i>vtable</i> for
class <b>Cylinder</b> points to the <b>Cylinder area</b> function
that calculates the surface area of the <b>Cylinder</b>, namely
<b>2</b>p<b>r2 + 2</b>p<b>rh</b>. The <b>Cylinder</b> <b>volume</b> function pointer
points to a <b>volume</b> function that returns p<b>r2h</b>. The
<b>Cylinder printShapeName</b> function pointer points to a
function that prints <tt><b>"Cylinder: "</b></tt>. The <b>Cylinder print</b>
function pointer points to its function that prints <b>[ x, y ]
r h</b>.<br>
<spacer width=16 height=1>Polymorphism is accomplished through a complex data
structure that involves three levels of pointers. So far,
we have discussed only one level--the function
pointers in the <i>vtable</i>. These pointers point to the actual <br>
</page>
<page>
functions to be executed when a <b>virtual</b> function is
invoked.<br>
<spacer width=16 height=1>Now we consider the second level of pointers.
Whenever an object of a class with <b>virtual</b> functions is
instantiated, the compiler attaches to the front of the
object a pointer to the <i>vtable</i> for that class. [Note: This
pointer is normally at the front of the object, but it is not
required to be implemented that way.]<br>
<spacer width=16 height=1>The third level of pointer is simply the handle on the
object that is receiving the <b>virtual</b> function call (this
handle may also be a reference).<br>
<spacer width=16 height=1>Now let us see how a typical <b>virtual</b> function call is
executed. Consider the call <br>
</page>
<page>
<font size=2><br></font><font size=11><pre>
baseClassPtr->printShapeName()<p>
</pre></font>
in function <b>virtualViaPointer</b>. Assume for the
following discussion that <b>baseClassPtr</b> contains the
address in <b>arrayOfShapes[ 1 ]</b> (i.e., the address of
object <b>circle</b>). When the compiler compiles this
statement, it determines that the call is indeed being
made off a base-class pointer and that
<b>printShapeName</b> is a <b>virtual</b> function.<br>
<spacer width=16 height=1>Next, the compiler determines that <b>printShapeName</b> is
the third entry in each of the <i>vtables</i>. To locate this
entry, the compiler notes that it will need to skip the
first two entries. Thus, the compiler compiles an <i>offset</i>
or <i>displacement</i> of 8 bytes (4 bytes for each pointer on <br>
</page>
<page>
today's popular 32-bit machines) into the machine
language object code that will execute the <b>virtual</b>
function call.<br>
<spacer width=16 height=1>Then, the compiler generates code that will (Note: The
numbers in the list below correspond to the circled
1. Select the <i>ith</i> entry from <b>arrayOfShapes</b> (in this case
the address of object <b>circle</b>) and pass it to <b>virtualViaPointer</b>. This sets <b>baseClassPtr</b> to point to <b>circle</b>.<br>
2. Dereference that pointer to get to the <b>circle</b> object--
which as you recall, begins with a pointer to the <b>Circle</b>
<i>vtable</i>.<br>
</page>
<page>
3. Dereference <b>circle</b>'s <i>vtable</i> pointer to get to the
<b>Circle</b> <i>vtable</i>.<br>
4. Skip the offset of 8 bytes to pick up the <b>printShapeName</b> function pointer.<br>
5. Dereference the <b>printShapeName</b> function pointer
to form the name of the actual function to be executed
and use the function call operator <tt><b>()</b></tt> to execute the
appropriate <b>printShapeName</b> function and print the
character string <tt><b>"Circle: "</b></tt>.<br>
The data structures of <a href="^Illustration::c:s0p1"><img src="bckgrnds/icons/ill_ico.gif" align=sidebar>Fig. 10.3</a> may appear to be
complex, but most of this complexity is managed by the
compiler and hidden from the programmer, making
polymorphic programming straightforward in C++.<br>
</page>
<page>
<a href="^Perform::c:s0p0"><img src="bckgrnds/icons/perf_ico.gif" align=sidebar></a>The pointer dereferencing operations and memory
accesses that occur on every <b>virtual</b> function call do
require some additional execution time. The <i>vtables</i> and
the <i>vtable</i> pointers added to the objects require some
additional memory.<br>
<spacer width=16 height=1><a href="^Perform::c:s0p1"><img src="bckgrnds/icons/perf_ico.gif" align=sidebar></a>Hopefully, you now have enough information about
how <b>virtual</b> functions operate to determine if using
A virtual function table is also known as a vtable. <br>
<component type="checkbox" width=20 height=18 label="" name="" feedback="False. The class is an abstract class if it has one or more 0s in its vtable. The 0s represent the class's pure virtual functions.">
Any class that has one or more 0s in its vtable is a concrete class. <br>
<component type=button name=b label="Check Your Answer" width=125 height=24>
<indent width=8 delay>* With <b>virtual</b> functions and polymorphism, it
becomes possible to design and implement systems that
are more easily extensible. Programs can be written to
process objects of types that may not exist when the
program is under development.</indent>
<indent width=8 delay>* Polymorphic programming with <b>virtual</b> functions
can eliminate the need for <b>switch</b> logic. The programmer can use the <b>virtual</b> function mechanism to perform
the equivalent logic automatically, thus avoiding the
kinds of errors typically associated with <b>switch</b> logic.
Client code making decisions about object types and </indent>
</page>
<page>
<indent width=8 delay>* representations indicates poor class design.</indent>
<indent width=8 delay>* Derived classes can provide their own implementations of a base class <b>virtual</b> function if necessary, but if
they do not, the base class's implementation is used.</indent>
<indent width=8 delay>* If a <b>virtual</b> function is called by referencing a specific object by name and using the dot member selection operator, the reference is resolved at compile time
(this is called <i>static binding</i>) and the <b>virtual</b> function
that is called is the one defined for (or inherited by) the
class of that particular object.</indent>
<indent width=8 delay>* There are many situations in which it is useful to
define classes for which the programmer never intends
to instantiate any objects. Such classes are called </indent>
</page>
<page>
<indent width=8 delay>* abstract classes. Because these are used only as base
classes, we will normally refer to them as abstract base
classes. No objects of an abstract class may be
instantiated in a program.</indent>
<indent width=8 delay>* Classes from which objects can be instantiated are
called concrete classes.</indent>
<indent width=8 delay>* A class is made abstract by declaring one or more of
its <b>virtual</b> functions to be pure. A pure <b>virtual</b> function
is one with an initializer of<b> = 0</b> in its declaration.</indent>
<indent width=8 delay>* If a class is derived from a class with a pure <b>virtual</b>
function without supplying a definition for that pure
<b>virtual</b> function in the derived class, then that <b>virtual</b>
function remains pure in the derived class. Conse</indent>
</page>
<page>
<indent width=8 delay>* quently, the derived class is also an abstract class (and
cannot have any objects).</indent>
<indent width=8 delay>* C++ enables polymorphism--the ability for objects
of different classes related by inheritance to respond
differently to the same member function call. </indent>
<indent width=8 delay>* Polymorphism is implemented via <b>virtual</b> functions. </indent>
<indent width=8 delay>* When a request is made through a base-class pointer
or reference to use a <b>virtual</b> function, C++ chooses the
correct overridden function in the appropriate derived
class associated with the object.</indent>
<indent width=8 delay>* Through the use of <b>virtual</b> functions and polymorphism, one member function call can cause different
actions depending on the type of the object receiving </indent>
</page>
<page>
<indent width=8 delay>* the call. </indent>
<indent width=8 delay>* Although we cannot instantiate objects of abstract
base classes, we can declare pointers to abstract base
classes. Such pointers can be used to enable polymorphic manipulations of derived-class objects when such
objects are instantiated from concrete classes.</indent>
<indent width=8 delay>* New kinds of classes are regularly added to systems.
New classes are accommodated by dynamic binding
(also called late binding). The type of an object need
not be known at compile time for a <b>virtual</b> function call
to be compiled. At execution time, the <b>virtual</b> function
call is matched with the member function of the receiving object. </indent>
</page>
<page>
<indent width=8 delay>* Dynamic binding enables independent software vendors (ISVs) to distribute software without revealing
proprietary secrets. Software distributions can consist
of only header files and object files. No source code
needs to be revealed. Software developers can then use
inheritance to derive new classes from those provided
by the ISVs. The software that works with the classes
the ISVs provide will continue to work with the derived
classes and will use (via dynamic binding) the overridden <b>virtual</b> functions provided in these classes.</indent>
<indent width=8 delay>* Dynamic binding requires that at execution time, the
call to a <b>virtual</b> member function be routed to the <b>virtual</b> function version appropriate for the class. A <b>vir</b></indent>
</page>
<page>
<indent width=8 delay>* <b>tual</b> function table called the <i>vtable</i> is implemented as
an array containing function pointers. Each class that
contains <b>virtual</b> functions has a <i>vtable</i>. For each <b>virtual</b> function in the class, the <i>vtable</i> has an entry containing a function pointer to the version of the <b>virtual</b>
function to use for an object of that class. The <b>virtual</b>
function to use for a particular class could be the function defined in that class, or it could be a function inherited either directly or indirectly from a base class higher
in the hierarchy.</indent>
<indent width=8 delay>* When a base class provides a <b>virtual</b> member function, derived classes can override the <b>virtual</b> function,
but they do not have to override it. Thus a derived class </indent>
</page>
<page>
<indent width=8 delay>* can use a base class's version of a <b>virtual</b> member
function, and this would be indicated in the <i>vtable</i>.</indent>
<indent width=8 delay>* Each object of a class with <b>virtual</b> functions contains
a pointer to the <i>vtable</i> for that class. The appropriate
function pointer in the <i>vtable</i> is obtained and dereferenced to complete the call at execution time. This
<i>vtable</i> lookup and pointer dereferencing require nominal execution time overhead, usually less than the best
possible client code.</indent>
<indent width=8 delay>* Declare the base-class destructor <b>virtual</b> if the class
contains <b>virtual</b> functions. This makes all derived-class
destructors <b>virtual</b> even though they do not have the
same name as the base-class destructor. If an object in </indent>
</page>
<page>
<indent width=8 delay>* the hierarchy is destroyed explicitly by applying the
<b>delete</b> operator to a base-class pointer to a derived-class
object, the destructor for the appropriate class is called.</indent>
<indent width=8 delay>* Any class that has one or more <b>0</b> pointers in its <i>vtable</i>
is an abstract class. Classes without any <b>0</b> <i>vtable</i> pointers (like <b>Point</b>, <b>Circle</b> and <b>Cylinder</b>) are concrete
classes.</indent>
</page>
<page>
<br>
</page>
</section>
<section type=Popup name=Debug title="Testing">
<page>
This chapter does not contain any Testing and Debugging tips.